package cn.bob.basic.service.impl;

import cn.bob.basic.config.BussinessException;
import cn.bob.basic.constant.BaseConstant;
import cn.bob.basic.dto.PhoneEmailDto;
import cn.bob.basic.service.IRegisterServer;
import cn.bob.basic.utils.MD5Utils;
import cn.bob.basic.utils.StrUtils;
import cn.bob.user.domain.Logininfo;
import cn.bob.user.domain.User;
import cn.bob.user.mapper.LogininfoMapper;
import cn.bob.user.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author bob
 * @data 2022/10/19-15:49
 */
@Slf4j
@Service
public class RegisterServerImpl implements IRegisterServer {
    @Autowired
    private LogininfoMapper logininfoMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 手机格式的注册
     * @param phoneDto
     */
    @Override
    public void phoneCreate(PhoneEmailDto phoneDto) {
        //校验手机格式
        phoneFormat(phoneDto);
        //密码，用户短信验证码校验
        String format = String.format(BaseConstant.VerifyCodeCons.PHONE_REDIS_KEY, phoneDto.getPhone());
        commonVerify(format,phoneDto);

        getConvert(phoneDto);
    }

    /**
     * 邮箱格式的注册
     * @param emailDto
     */
    @Override
    public void emailCreate(PhoneEmailDto emailDto) {

        emailFormat(emailDto);
        //密码，用户短信验证码校验
        String format = String.format(BaseConstant.VerifyCodeCons.PHONE_REDIS_KEY, emailDto.getEmail());
        commonVerify(format,emailDto);

        getConvert(emailDto);
    }



    //表之间的转换将Dto转换为user，user表转换为logininfo存储
    private void getConvert(PhoneEmailDto phoneDto) {
        User user = dtoConvertUser(phoneDto);
        Logininfo logininfo = userConvertlogin(user);
        //创建为普通用户
        logininfo.setType(1);
        logininfoMapper.add(logininfo);
        user.setLogininfoId(logininfo.getId());
        userMapper.add(user);
    }

    //用户密码验证码校验
    private void commonVerify(String SCode,PhoneEmailDto Dto) {
        //判断两次密码是否一致
        if (!Dto.getPassword().equals(Dto.getPasswordRepeat())){
            throw new BussinessException("两次输入的密码不一致！！");
        }
        //判断手机验证码是否一致    判断注册手机和接收短信的手机是否一致
        String phoneCode = (String) redisTemplate.opsForValue().get(SCode);
        if (StringUtils.isBlank(phoneCode)){
            //判断手机验证码 通过手机号去redis中获取数据没获取到，册手机和接收短信的手机不一致
            throw new BussinessException("验证码错误!!");
        }
        //避免非空切割
        String[] split = phoneCode.split(":");
        String smsCode = Dto.getSmsCode();
        if (!split[0].equals(smsCode)){
            throw new BussinessException("验证码错误!!");
        }
    }

    //校验邮箱格式
    private void emailFormat(PhoneEmailDto emailDto) {
        //判断邮箱格式是否一致、
        String tegex="[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[\\w](?:[\\w-]*[\\w])?";
        boolean flag= emailDto.getEmail().matches(tegex);
        System.out.println(!flag);
        if (!flag){
            throw new BussinessException("邮箱格式错误！！");
        }
        if (StringUtils.isBlank(emailDto.getEmail())){
            throw new BussinessException("邮箱不能为空！！");
        }
    }
    //校验手机格式
    private void phoneFormat(PhoneEmailDto phoneDto) {
        Pattern p = Pattern.compile("^((13[0-9])|(15[^4,\\D])|(18[0-9]))\\d{8}$");
        Matcher m = p.matcher(phoneDto.getPhone());
        boolean matches = m.matches();
        if (!matches){
            throw new BussinessException("手机格式错误！！");
        }
        if (StringUtils.isBlank(phoneDto.getPhone())){
            throw new BussinessException("手机号不能为空！！");
        }
    }

    //将user转换为Logininfo
    public Logininfo userConvertlogin(User user){
        Logininfo logininfo = new Logininfo();
        BeanUtils.copyProperties(user,logininfo);
        return logininfo;
    }

    //将PhoneEmailDto转换为user
    public User dtoConvertUser(PhoneEmailDto Dto){
        //获取盐值
        String salt = StrUtils.getComplexRandomString(32);
        String pwd = MD5Utils.encrypByMd5(salt + Dto.getPassword());
        if (Dto.getPhone()==null){
            return User.builder()
                    .username(Dto.getEmail())
                    .email(Dto.getEmail())
                    .salt(salt)
                    .password(pwd)
                    .build();
        }
        return User.builder()
                .username(Dto.getPhone())
                .phone(Dto.getPhone())
                .salt(salt)
                .password(pwd)
                .build();
    }

}
